﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BookingDB.Models;
using GenericModels;

namespace CTRLayer
{
    public class CTRShow
    {
        private BioBookingContext db;

        public CTRShow()
        {
            db = new BioBookingContext();
        }

        /// <summary>
        /// Retrieves the showroom associated with the desired show
        /// </summary>
        /// <param name="show_Id"></param>
        /// <returns>ShowRoom</returns>
        public ShowRoom GetShowRoomOnShowId(int show_Id)
        {
            EntityShowRoom eShowRoom = (from sr in db.ShowRooms
                                        join s in db.Shows on sr.roomNumber equals s.id
                                        where s.id == show_Id
                                        select sr).SingleOrDefault();

            return TranslateShowRoom(eShowRoom);
        }

        /// <summary>
        /// Retrieves the show type, that is associated with the desired show
        /// </summary>
        /// <param name="show_Id"></param>
        /// <returns>ShowType</returns>
        public ShowType GetTypeOnShowId(int show_Id)
        {
            EntityShowType eType = (from st in db.ShowTypes
                                    join s in db.Shows on st.id equals s.type_Id
                                    where s.id == show_Id
                                    select st).SingleOrDefault();
            return TranslateShowType(eType);
        }

         //<summary>
         //Retrieves the prices associated with the desired show
         //</summary>
         //<param name="show_Id"></param>
         //<returns>Returns priceList</returns>
        public List<Price> GetPrice(int show_Id)
        {
            List<Price> prices = new List<Price>();

            IQueryable<EntityPrice> ePrices = (from ep in db.Prices
                                         join s in db.Shows on ep.id equals s.id
                                         select ep);

            foreach (EntityPrice ep in ePrices)
            {
                prices.Add(TranslatePrices(ep));
            }
            return prices;
        }

         //<summary>
         //Retrieves a show, and it´s associated components, based on the show id
         //</summary>
         //<param name="show_Id"></param>
         //<returns>Returns a complete show</returns>
        public Show GetShow(int show_Id)
        {
            EntityShow eShow = (from s in db.Shows
                                where s.id == show_Id
                                select s).SingleOrDefault();

            return TranslateShow(eShow);
        }

        /// <summary>
        /// Retrieves all shows playing on a given date
        /// </summary>
        /// <param name="date"></param>
        /// <returns>A list of the shows for the param date</returns>
        public List<Show> GetShowsByDate(DateTime date)
        {
            List<Show> shows = new List<Show>();

            IQueryable<EntityShow> eShows = (from s in db.Shows
                                             where s.date == date
                                             select s);
            foreach (EntityShow es in eShows)
            {
                shows.Add(TranslateShow(es));
            }

            return shows;
        }

        /// <summary>
        /// Retrieves all the shows
        /// </summary>
        /// <returns>A list containing all shows</returns>
        public List<Show> GetAllShows()
        {

            List<Show> allTheShows = new List<Show>();

            IQueryable<EntityShow> eShows = (from s in db.Shows
                                             select s);

            foreach (EntityShow es in eShows)
            {
                allTheShows.Add(TranslateShow(es));
            }
            return allTheShows;
        }


        #region Translate Methods
        /// <summary>
        /// Helper method which translates the retrieved entity framework object into a generic model
        /// Employs the use of GetPrice() as there are no direct connection between eShow and the price model.
        /// </summary>
        /// <param name="eShow"></param>
        /// <returns>A complete show</returns>
        private Show TranslateShow(EntityShow eShow)
        {
            Show s = new Show();

            s.Room = TranslateShowRoom(eShow.ShowRoom);
            s.Type = TranslateShowType(eShow.ShowType);
            s.Date = (DateTime)eShow.date;
            s.Show_Id = eShow.id;
            s.ImageDir = eShow.imageDir;

            List<Price> list = GetPrice(eShow.id);
            foreach (Price p in list)
            {
                s.Prices.Add(p);
            }

            return s;
        }

        /// <summary>
        /// Helper method which translates the retrieved entity framework object into a generic model
        /// </summary>
        /// <param name="eShowRoom"></param>
        /// <returns>A ShowRoom</returns>
        private ShowRoom TranslateShowRoom(EntityShowRoom eShowRoom)
        {
            ShowRoom sr = new ShowRoom();

            try
            {
                sr.RoomNumber = eShowRoom.roomNumber;
                sr.Col = eShowRoom.col;
                sr.Row = eShowRoom.row;
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: " + e);
            }
            return sr;
        }

        /// <summary>
        /// Helper method which translates the retrieved entity framework object into a generic model
        /// </summary>
        /// <param name="eType"></param>
        /// <returns>A ShowType</returns>
        private ShowType TranslateShowType(EntityShowType eType)
        {
            ShowType st = new ShowType();

            try
            {

                st.Description = eType.description;
                st.Release = (DateTime)eType.release;
                st.Title = eType.title;
                st.Type = eType.type;
            }
            catch (NullReferenceException nex)
            {
                Console.WriteLine("Error: " + nex);
            }
            return st;
        }

        /// <summary>
        ///  Helper method which translates the retrieved entity framework object into a generic model
        /// </summary>
        /// <param name="ePrice"></param>
        /// <returns>A Price</returns>
        public Price TranslatePrices(EntityPrice ePrice)
        {
            Price p = new Price();

            p.TicketId = ePrice.id;
            p.TicketPrice = (float)ePrice.price1;
            p.TicketType = ePrice.type;

            return p;
        }
        #endregion
    }
}
